﻿using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Main : MonoBehaviour
{
    //记录水果得个数
    public GameObject[] prefabs;
    public GameObject[] effects;
    //
    public GameObject[,] objects;
    //列
    public int Column;
    //行
    public int Row;
    //开始的时间
    public float Timestart;
    public Transform Border;
    public Text text;
    public int Score;
    //缓存
    List<GameObject> cache = new List<GameObject>();
    public int Size;
    // Start is called before the first frame update
    void Start()
    {
        objects = new GameObject[Column, Row];
        //间隔宽度
        float x = -0.5f * Column * Size + 0.5f * Size;
        float y = -0.5f * Row * Size + 0.5f * Size;
        //max记住最大得长度
        int max = prefabs.Length;
        for (int i = 0; i < Column; i++)
        {
            for (int j = 0; j < Row; j++)
            {
                //随机生成
                int index = Random.Range(0, max);
                GameObject go = GameObject.Instantiate(prefabs[index]);
                //设置变换的父级 transform
                go.transform.SetParent(transform);
                //相对于父变换的变换位置
                go.transform.localPosition = new Vector3(i * Size + x, j * Size + y, 0);
                //位置
                //transform.position = new Vector3(-8, -4.5f, 0);
                //图像大小
                go.transform.localScale = new Vector3(Size, Size, Size);

                //AddComponent 将该组件类添加到该游戏对象
                Mark mark = go.AddComponent<Mark>();
                mark.Column = i;
                mark.Row = j;
                mark.Index = index;
                mark.name = index.ToString();
                go.AddComponent<BoxCollider2D>();
                objects[i, j] = go;
            }
        }
    }
    // Update is called once per frame
    void Update()
    {
        if (Timestart > 0)
        {
            Timestart -= Time.deltaTime;
        }
        if (Timestart < 0)
        {
            if (Input.GetMouseButtonDown(0))
            {
                Debug.Log(111);
                //创建一条射线
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction);
                //判断该目标是否为NUILL
                if (hit.transform != null)
                {
                    Border.gameObject.SetActive(true );
                    Border.position  = hit.transform.position;
                    Debug.Log(222);
                    lastCol = curCol;
                    lastRow = CurRow;
                    Mark mark = hit.transform.GetComponent<Mark>();
                    curCol = mark.Column;
                    CurRow = mark.Row;
                    //清空一下缓存
                    cache.Clear();
                    Check(hit.transform.gameObject.name, mark.Column, mark.Row);
                    if (cache.Count >= 3)
                    {
                        AddScore(cache.Count);
                        PlayDestory();
                        Debug.Log(333);
                    }
                    else
                    {
                        //Debug.Log(string.Format(" ddd  ge {0}", cache.Count));
                        //Debug.LogFormat(" ddd  ge {0}", cache.Count);
                        Debug.Log($" ddd  ge {cache.Count}");
                        Debug.Log($" ddd  ge {(cache.Count == 0 ? -1 : 2)}");
                        Debug.Log($" ddd  ge {(cache.Count == 0 ? "AA": "bb")}");
                        Debug.Log($"{nameof(Main)}: ");
                        Debug.Log($"{nameof(Main)}: 骄傲发生的{cache.Count}");

                        cache.Clear();
                        Swap();
                    }
                }
            }
        }
    }
    void Check(string type, int column, int row)
    {
        if (row < 0 || row >= Row || column < 0 || column >= Column)
            return;
        GameObject go = objects[column, row];
        //类型是否一样
        if (go.name != type)
            return;
        //防止重复添加
        if (cache.Contains(go))
            return;
        cache.Add(go);
        Check(type, column, row - 1);
        Check(type, column, row + 1);
        Check(type, column - 1, row);
        Check(type, column + 1, row);
    }
    void PlayDestory()
    {
        float x = -0.5f * Column * Size + 0.5f * Size;
        float y = -0.5f * Row * Size + 0.5f * Size;
        for (int i = 0; i < cache.Count; i++)
        {
            Mark mark = cache[i].GetComponent<Mark>();
            objects[mark.Column, mark.Row] = null;
            GameObject go = GameObject.Instantiate(effects[mark.Index]);
            go.transform.SetParent(transform);
            go.transform.position = new Vector3(mark .Column *Size +x,mark .Row *Size +y,0);
            go.transform.localScale = new Vector3(Size, Size, Size);
            GameObject.Destroy(cache[i]);
        }
        StartCoroutine(Wait(0.6f,Fall));
        //Fall();
    }
    IEnumerator Wait(float time, System.Action action)
    {
        yield return new WaitForSeconds(time);
        action();
    }

    void Fall()
    {
        float x = -0.5f * Column * Size + 0.5f * Size;
        float y = -0.5f * Row * Size + 0.5f * Size;
        for (int i = 0; i < Column; i++)
        {
            int count = 0;
            for (int j = 0; j < Row; j++)
            {
                if (objects[i, j] == null)
                {
                    count++;
                }
                else 
                {
                    if (count > 0)
                    {
                        Mark m = objects[i, j].GetComponent<Mark>();
                        int row = j - count;
                        m.Row = row;
                        objects[i, row] = objects[i, j];
                        objects[i, row].transform.DOMove(new Vector3(i * Size + x, row * Size + y, 0), 0.3f);
                        objects[i, j] = null;
                    }
                }
            }
        }
        Add();
    }
    void Add()
    {
        float x = -0.5f * Column * Size + 0.5f * Size;
        float y = -0.5f * Row * Size + 0.5f * Size;
        //max记住最大得长度
        int max = prefabs.Length;
        for (int i = 0; i < Column; i++)
        {
            for (int j = 0; j < Row; j++)
            {
                if (objects[i, j] == null)
                {
                    max = prefabs.Length;
                    //随机生成
                    int index = Random.Range(0, max);
                    GameObject go = GameObject.Instantiate(prefabs[index]);
                    //设置变换的父级 transform
                    go.transform.SetParent(transform);
                    //相对于父变换的变换位置
                    go.transform.localPosition = new Vector3(i * Size + x, (Row + 1) * Size + y, 0);

                    go.transform.DOMove(new Vector3(i * Size + x, j * Size + y, 0), 0.3f);
                    //位置
                    //transform.position = new Vector3(-8, -4.5f, 0);
                    //图像大小
                    go.transform.localScale = new Vector3(Size, Size, Size);

                    //AddComponent 将该组件类添加到该游戏对象
                    Mark mark = go.AddComponent<Mark>();
                    mark.Column = i;
                    mark.Row = j;
                    mark.Index = index;
                    mark.name = index.ToString();
                    go.AddComponent<BoxCollider2D>();
                    objects[i, j] = go;
                }
            }
        }
    }
    int curCol, CurRow;
    int lastCol, lastRow;
    void Swap()
    {
        int ox = curCol - lastCol;
        int oy = CurRow - lastRow;
        if (oy==0)
        {
            if (ox == 1 || ox == -1)
            {
                SwapTest();
            }
        }
        else if(ox==0)
        {
            if (oy == 1 || oy == -1)
            {
                SwapTest();
            }
        }
    }
    void SwapTest()
    {
        bool fail = true;
        //交换
        GameObject a = objects[curCol, CurRow];
        GameObject b = objects[lastCol, lastRow];
        objects[curCol, CurRow] = b;
        objects[lastCol, lastRow] = a;
        var mb = b.GetComponent<Mark>();
        mb.Column = curCol;
        mb.Row = CurRow;
        var ma = a.GetComponent<Mark>();
        ma.Column = lastCol;
        ma.Row = lastRow;
        int cc = curCol;
        int cr = CurRow;
        int lc = lastCol;
        int lr = lastRow;
        a.transform.DOMove(b.transform .position ,0.3f);
        b.transform.DOMove(a.transform.position, 0.3f).onComplete = () =>
        {

            cache.Clear();
            Check(b.name, cc, cr);
            int c = 0;
            if (cache.Count >= 3)
            {
                c += cache.Count;
                fail = false;
                PlayDestory();
            }
            cache.Clear();
            Check(a.name ,lc,lr );
            if (cache.Count >= 3)
            {
                c += cache.Count;
                fail = false;
                PlayDestory();
            }
            cache.Clear();
            AddScore(c);
            if (fail)
            {
                objects[cc, cr] = a;
                objects[lc, lr] = b;
                a.transform.DOMove(b.transform.position, 0.3f);
                b.transform.DOMove(a.transform.position, 0.3f);
                ma.Column = cc ;
                ma.Row = cr;
                mb.Column = lc;
                mb.Row = lr;
            }
        };

    }
    void AddScore(int count)
    {
        if (count < 3) 
            return;
        Score += count * 100;
        count -= 3;
        Score += count * count * 10;
        text.text = Score.ToString();
    }
}
